﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using SPListsCaller.WS;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.IO;
using System.Xml;
using System.ComponentModel;
using System.Data;
using System.Collections.ObjectModel;

namespace SPListsCaller.Data
{
    [Serializable]
    [XmlRoot]
    public class GetListItemsModel : INotifyPropertyChanged
    {
        //---------------------------------------------------------------------
        #region Variables & accesseurs
        //---------------------------------------------------------------------

        [XmlIgnore]
        public NetworkCredential Credential { get; set; }

        [XmlAttribute]
        public string Domain
        {
            get { return Credential.Domain; }
            set { Credential.Domain = value; OnPropertyChanged("Domain"); }
        }

        [XmlAttribute]
        public string Login
        {
            get { return Credential.UserName; }
            set { Credential.UserName = value; OnPropertyChanged("Login"); }
        }

        [XmlAttribute]
        public string Password
        {
            get { return Credential.Password; }
            set { Credential.Password = value; OnPropertyChanged("Password"); }
        }

        [XmlElement]
        public GetListItems_CallParameters QueryParams { get; set; }

        private string _url;
        [XmlAttribute]
        public string Url
        {
            get { return _url; }
            set { _url = value; OnPropertyChanged("Url"); }
        }

        private DataTable _currentDataTable;
        [XmlIgnore]
        public DataTable CurrentDataTable
        {
            get { return _currentDataTable; }
            set
            {
                _currentDataTable = value;
                List<string> bufferFieldNames = _currentDataTable.Columns.Cast<DataColumn>()
                                    .Select(col => col.ColumnName).ToList();

                CurrentFieldNames.Clear();
                foreach (string fieldName in bufferFieldNames)
                {
                    CurrentFieldNames.Add(fieldName);
                }

                OnPropertyChanged("CurrentFieldNames");
                OnPropertyChanged("TableItemsCount");
            }
        }

        [XmlIgnore]
        public ObservableCollection<string> CurrentFieldNames { get; set; }


        [XmlIgnore]
        public int TableItemsCount
        {
            get
            {
                int result = 0;

                if (CurrentDataTable != null)
                {
                    result = CurrentDataTable.Rows.Count;
                }

                return result;
            }
        }

        [XmlIgnore]
        public int XmlItemsCount
        {
            get
            {
                int result = 0;

                if (CurrentDataTable != null)
                {
                    result = CurrentDataTable.Rows.Count;
                }

                return result;
            }
        }

        private bool _isPopupVisible = true;
        [XmlIgnore] // Future
        public bool IsPopupVisible
        {
            get
            {
                return _isPopupVisible;
            }
            set
            {
                _isPopupVisible = value;
                OnPropertyChanged("IsPopupVisible");
            }
        }
        //---------------------------------------------------------------------
        #endregion Variables & accesseurs
        //---------------------------------------------------------------------


        //---------------------------------------------------------------------
        #region Initialisations
        //---------------------------------------------------------------------

        public GetListItemsModel()
        {
            Credential = new NetworkCredential();
            QueryParams = new GetListItems_CallParameters();
            CurrentFieldNames = new ObservableCollection<string>();

            InitializeDefault();
        }

        public void InitializeDefault()
        {
            this.Url = @"http://..../_vti_bin/lists.asmx";

            this.QueryParams.ListName = @"{17991794-81BB-494F-9910-CFBF1093A7CF} -ou- Bibliothèque de documents";
            this.QueryParams.ViewName = @"{7137FFF8-48FF-4C69-8C76-0E3BBD1EA7F9}";
            this.QueryParams.QueryOptions = @"<IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns>";
            this.QueryParams.Query = "<Where><Gt><FieldRef Name=\"ID\" /><Value Type=\"Counter\">3</Value></Gt></Where>";
            this.QueryParams.ViewFields = "<FieldRef Name=\"Title\" />";

            this.Credential.Domain = "DOMCTR";
            this.Credential.UserName = "???";

            this.QueryParams.RowLimit = 150;
        }

        //---------------------------------------------------------------------
        #endregion Initialisations
        //---------------------------------------------------------------------


        //---------------------------------------------------------------------
        #region Enregistrement & Chargement
        //---------------------------------------------------------------------

        public XElement ToXElement()
        {
            XElement result = null;

            using (MemoryStream stream = new MemoryStream())
            {
                XmlSerializer xSer = new XmlSerializer(typeof(GetListItemsModel));
                xSer.Serialize(stream, this);
                stream.Position = 0;

                using (XmlReader reader = XmlReader.Create(stream))
                {
                    result = XElement.Load(reader);
                }
            }


            return result;
        }

        public static GetListItemsModel FromXElement(XElement source)
        {
            GetListItemsModel result = null;

            XmlSerializer xs = new XmlSerializer(typeof(XElement));
            using (MemoryStream ms = new MemoryStream())
            {
                xs.Serialize(ms, source);
                ms.Position = 0;

                xs = new XmlSerializer(typeof(GetListItemsModel));
                object obj = xs.Deserialize(ms);

                result = obj as GetListItemsModel;
            }

            return result;
        }

        public void SaveAs(string filePath)
        {
            XElement xmlData = this.ToXElement();
            xmlData.Save(filePath);
        }

        public static GetListItemsModel FromFile(string filePath)
        {
            XElement xmlData = XElement.Load(filePath);
            GetListItemsModel result = GetListItemsModel.FromXElement(xmlData);

            return result;
        }

        public void LoadFrom(string filePath)
        {
            XElement xmlData = XElement.Load(filePath);
            GetListItemsModel buffer = GetListItemsModel.FromXElement(xmlData);

            this.Domain = buffer.Domain;
            this.Login = buffer.Login;
            this.Url = buffer.Url;

            foreach (PropertyDescriptor propDescr in TypeDescriptor.GetProperties(buffer.QueryParams))
            {
                object propValue = propDescr.GetValue(buffer.QueryParams);
                if (propValue != null)
                {
                    propDescr.SetValue(this.QueryParams, propValue);
                }
            }
        }
        //---------------------------------------------------------------------
        #endregion Enregistrement & Chargement
        //---------------------------------------------------------------------


        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
